using BackOffice.Application.Services;
using Backoffice.Domain.Repositories;
using Backoffice.Domain.Entities.App;
using BackOffice.Application.DTOs;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
using BackOffice.Application.Common;
using System.IO;

namespace BackOffice.Api.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class FileController : ControllerBase
    {
        private readonly IFileService _fileService;
        private readonly IRepository<AppFile> _fileRepo;
        private readonly ILogService _logService;

        public FileController(IFileService fileService, IRepository<AppFile> fileRepo, ILogService logService)
        {
            _fileService = fileService;
            _fileRepo = fileRepo;
            _logService = logService;
        }

        // 上传文件
        [HttpPost("upload")]
        public async Task<IActionResult> Upload([FromBody] UploadFileDto dto)
        {
            try
            {
                var res = await _fileService.UploadFileAsync(dto);
                
                if (res.Code == 10000)
                {
                    await LogHelper.LogInfoAsync(_logService, HttpContext, "上传文件", $"上传文件: {dto.FileName}");
                    return Ok(res.Data);
                }
                else
                {
                    await LogHelper.LogWarningAsync(_logService, HttpContext, "上传文件失败", $"上传文件失败: {dto.FileName} - {res.Msg}");
                    return BadRequest(res);
                }
            }
            catch (Exception ex)
            {
                await LogHelper.LogErrorAsync(_logService, HttpContext, "上传文件异常", $"上传文件异常: {dto.FileName} - {ex.Message}");
                throw;
            }
        }

        // 更新文件信息
        [HttpPut("update/{id}")]
        public async Task<IActionResult> Update(Guid id, [FromBody] UpdateFileDto dto)
        {
            var res = await _fileService.UpdateFileAsync(id, dto);
            return res.Code == 10000 ? Ok(res.Data) : BadRequest(res);
        }

        // 删除文件
        [HttpDelete("delete/{id}")]
        public async Task<IActionResult> Delete(Guid id)
        {
            try
            {
                // 先获取文件信息用于日志记录
                var file = await _fileRepo.GetByIdAsync(id);
                var fileName = file?.FileName ?? "未知文件";
                
                var res = await _fileService.DeleteFileAsync(id);
                
                if (res.Code == 10000)
                {
                    await LogHelper.LogInfoAsync(_logService, HttpContext, "删除文件", $"删除文件: {fileName} (ID: {id})");
                    return Ok(res.Data);
                }
                else
                {
                    await LogHelper.LogWarningAsync(_logService, HttpContext, "删除文件失败", $"删除文件失败: {fileName} (ID: {id}) - {res.Msg}");
                    return BadRequest(res);
                }
            }
            catch (Exception ex)
            {
                await LogHelper.LogErrorAsync(_logService, HttpContext, "删除文件异常", $"删除文件异常: ID {id} - {ex.Message}");
                throw;
            }
        }

        // 获取文件列表
        [HttpGet("list")]
        public async Task<IActionResult> GetFiles([FromQuery] Guid? folderId)
        {
            var res = await _fileService.GetFileListAsync(folderId);
            return res.Code == 10000 ? Ok(res.Data) : BadRequest(res);
        }

        // 移动文件
        [HttpPost("move/{id}")]
        public async Task<IActionResult> Move(Guid id, [FromBody] MoveFileDto dto)
        {
            var res = await _fileService.MoveFileAsync(id, dto.TargetFolderId);
            return res.Code == 10000 ? Ok(res.Data) : BadRequest(res);
        }

        // 创建文件夹
        [HttpPost("create-folder")]
        public async Task<IActionResult> CreateFolder([FromBody] CreateFolderDto dto)
        {
            var res = await _fileService.CreateFolderAsync(dto);
            return res.Code == 10000 ? Ok(res.Data) : BadRequest(res);
        }

        // 更新文件夹信息
        [HttpPut("update-folder/{id}")]
        public async Task<IActionResult> UpdateFolder(Guid id, [FromBody] UpdateFolderDto dto)
        {
            var res = await _fileService.UpdateFolderAsync(id, dto);
            return res.Code == 10000 ? Ok(res.Data) : BadRequest(res);
        }

        // 删除文件夹
        [HttpDelete("delete-folder/{id}")]
        public async Task<IActionResult> DeleteFolder(Guid id)
        {
            var res = await _fileService.DeleteFolderAsync(id);
            return res.Code == 10000 ? Ok(res.Data) : BadRequest(res);
        }

        // 获取文件夹树
        [HttpGet("folder-tree")]
        public async Task<IActionResult> GetFolderTree([FromQuery] Guid? parentId)
        {
            var res = await _fileService.GetFolderTreeAsync(parentId);
            return res.Code == 10000 ? Ok(res.Data) : BadRequest(res);
        }

        // 分享文件
        [HttpPost("share/{fileId}")]
        public async Task<IActionResult> ShareFile(Guid fileId, [FromBody] ShareFileDto dto)
        {
            var res = await _fileService.ShareFileAsync(fileId, dto);
            return res.Code == 10000 ? Ok(res.Data) : BadRequest(res);
        }

        // 撤销分享
        [HttpPost("revoke-share/{shareId}")]
        public async Task<IActionResult> RevokeShare(Guid shareId)
        {
            var res = await _fileService.RevokeShareAsync(shareId);
            return res.Code == 10000 ? Ok(res.Data) : BadRequest(res);
        }

        // 设置文件权限
        [HttpPost("set-acl/{fileId}")]
        public async Task<IActionResult> SetFileAcl(Guid fileId, [FromBody] SetFileAclDto dto)
        {
            var res = await _fileService.SetFileAclAsync(fileId, dto);
            return res.Code == 10000 ? Ok(res.Data) : BadRequest(res);
        }
                // 文件多条件查询
        [HttpPost("search")]
        public async Task<IActionResult> Search([FromBody] FileSearchDto dto)
        {
            var res = await _fileService.SearchFilesAsync(dto);
            return res.Code == 10000 ? Ok(res.Data) : BadRequest(res);
        }

        // 下载文件
        [HttpGet("download/{id}")]
        public async Task<IActionResult> Download(Guid id)
        {
            try
            {
                var file = await _fileRepo.GetByIdAsync(id);
                if (file == null)
                {
                    await LogHelper.LogWarningAsync(_logService, HttpContext, "下载文件失败", $"文件不存在: ID {id}");
                    return NotFound("文件不存在");
                }

                // 从相对路径中提取文件名
                var fileName = Path.GetFileName(file.RelativePath.TrimStart('/'));
                var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "uploads", fileName);
                
                if (!System.IO.File.Exists(filePath))
                {
                    await LogHelper.LogWarningAsync(_logService, HttpContext, "下载文件失败", $"文件不存在于磁盘: {filePath}");
                    return NotFound("文件不存在于磁盘");
                }

                var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
                
                await LogHelper.LogInfoAsync(_logService, HttpContext, "下载文件", $"下载文件: {file.FileName} (ID: {id})");
                
                return File(fileBytes, file.MimeType, file.FileName);
            }
            catch (Exception ex)
            {
                await LogHelper.LogErrorAsync(_logService, HttpContext, "下载文件异常", $"下载文件异常: ID {id} - {ex.Message}");
                return StatusCode(500, "下载文件时发生错误");
            }
        }
    }
}